package tv.accedo.achi.service;

import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.springframework.stereotype.Component;

import tv.accedo.achi.dao.AppDao;
import tv.accedo.achi.dao.CampDao;
import tv.accedo.achi.dao.UserDao;
import tv.accedo.achi.model.Achi;
import tv.accedo.achi.model.Camp;
import tv.accedo.achi.model.User;

/**
 * The business logic service of Campaign relevant functionality
 * @author Bo Liang
 *
 */
@Component
public class CampService {
	private User user; //injection
	private UserDao userDao; //injection
	private Camp camp; //injection
	private CampDao campDao; //injection
	private Achi achi; //injection
	private AppDao appDao; //injection

	/**
	 * Get all campaigns in two categories : unlocked and locked.
	 * <p>unlocked campaigns have a state value 'true',
	 * and locked campaigns have a state value 'false'.<br>
	 * in front-end, the true state will make the campaign colored,
	 * and the false state will make the campaign dim.
	 * @param username	user name
	 * @return			JSON camps
	 */
	public String getJsonCampsByUsername(String username) {
		List<Camp> campList = new ArrayList<Camp>(); 
		Map<Integer, String> unlockedCampIdMap = new HashMap<Integer, String>();
		String state = "none";
		user = userDao.getUserByUsername(username);
		// get all available campaigns to the campaign List
		campList = campDao.getAvailableCamps();
		// get user unlocked campaigns id to the unlocked campaign id list
		unlockedCampIdMap = campDao.getUnlockedCampsIdByUserId(user.getId());
		Format dateFormat = new SimpleDateFormat("yyyy.MM.dd E HH:mm");
		String jsonCamps = "]}";
		for (Iterator<Camp> iter = campList.iterator(); iter.hasNext(); ) {
			camp = iter.next();
			if (unlockedCampIdMap.containsKey(camp.getId())) {
				state = unlockedCampIdMap.get(camp.getId());	// true means user already unlocked this campaign and will colored displayed in front-end
			} else {
				state = "none";	// false means user did not unlock this campaign and will dim displayed in front-end
			}
			jsonCamps = "{camp_sn:'" + camp.getCamp_sn() 
					+ "', camp_name:'" + camp.getCamp_name() 
					+ "', camp_end:'" + dateFormat.format(camp.getCamp_end()) 
					+ "', state:'" + state + "'},"
					+ jsonCamps;
		}
		jsonCamps = "{camps:[" + jsonCamps;
		try {
			Thread.sleep(2200);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return jsonCamps; 	
	}
	
	public String getJsonCampsByUsernameForFriendShow(String username) {
		List<Camp> campList = new ArrayList<Camp>(); 
		Map<Integer, String> unlockedCampIdMap = new HashMap<Integer, String>();
		String state = "none";
		user = userDao.getUserByUsername(username);
		// get all available campaigns to the campaign List
		campList = campDao.getAvailableCamps();
		// get user unlocked campaigns id to the unlocked campaign id list
		unlockedCampIdMap = campDao.getUnlockedCampsIdByUserId(user.getId());
		
		String jsonCamps = "]}";
		String jsonCampsFinished = "";
		String jsonCampsPlaying = ""; 
		String jsonCampsNone = "";
		Format dateFormat = new SimpleDateFormat("yyyy.MM.dd E HH:mm");
		
		for (Iterator<Camp> iter = campList.iterator(); iter.hasNext(); ) {
			camp = iter.next();
			if (unlockedCampIdMap.containsKey(camp.getId())) {
				state = unlockedCampIdMap.get(camp.getId());	// true means user already unlocked this campaign and will colored displayed in front-end
				if (state == "finished") {
					jsonCampsFinished = "{camp_sn:'" + camp.getCamp_sn() 
									+ "', camp_name:'" + camp.getCamp_name() 
									+ "', camp_end:'" + dateFormat.format(camp.getCamp_end())
									+ "', state:'" + state + "'},"
									+ jsonCampsFinished;
				} else if (state == "playing") {
					jsonCampsPlaying =  "{camp_sn:'" + camp.getCamp_sn() 
									+ "', camp_name:'" + camp.getCamp_name() 
									+ "', camp_end:'" + dateFormat.format(camp.getCamp_end())
									+ "', state:'" + state + "'},"
									+ jsonCampsPlaying;
				}
			} else {
				state = "none";	// false means user did not unlock this campaign and will dim displayed in front-end
				jsonCampsNone =  "{camp_sn:'" + camp.getCamp_sn() 
							 + "', camp_name:'" + camp.getCamp_name() 
							 + "', camp_end:'" + dateFormat.format(camp.getCamp_end())
							 + "', state:'" + state + "'},"
							 + jsonCampsNone;
			}
		}
		jsonCamps = "{camps:[" + jsonCampsFinished + jsonCampsPlaying + jsonCampsNone + jsonCamps;
		try {
			Thread.sleep(2200);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return jsonCamps; 	
	}
	
	/**
	 * Return the achievements list with whether user unlocked or not, that belongs to the campaign.
	 * <p>campaign includes batch of achievements.<br>
	 * This function return the name of achievement and the application it belongs to, and state of the user whether unlocked it or not.
	 * @param camp_sn	campaign serial number
	 * @param username	user name
	 * @return			JSON format campAchis
	 */
	public String getJsonAchisByCampsnAndUsername(String camp_sn, String username) {
		List<String> achiSnList = new ArrayList<String>(); 
		Set<Achi> achiSet = new HashSet<Achi>(); 
		String jsonAchis = "]}";
		
		// get all achievements belongs to the campaign
		achiSet = campDao.getAchisByCampsn(camp_sn); 
		user = userDao.getUserByUsername(username); 
		
		// get user's unlocked achievements sn into achievement sn list
		for (Iterator<Achi> iterUser = user.getAchis().iterator(); iterUser.hasNext(); ) {
			achiSnList.add(iterUser.next().getAchi_sn()); 
		}
		
		for (Iterator<Achi> iter = achiSet.iterator(); iter.hasNext(); ) {
			achi = iter.next(); 
			String app_sn = achi.getApp_sn(); 
			String app_name = appDao.getAppByAppsn(app_sn).getApp_name();
			boolean state = false; 
			// if this achievement belongs the user's unlocked achievement list, assign the start in true
			if (achiSnList.contains(achi.getAchi_sn())) {
				state = true;
			}
			
			jsonAchis = "{app_sn:'" + app_sn 
					+ "', app_name:'" + app_name 
					+ "', achi_sn:'" + achi.getAchi_sn()
					+ "', achi_name:'" + achi.getAchi_name() 
					+ "', state:'" + state + "'},"
				+ jsonAchis;
		}
		jsonAchis = "{campAchis:[" + jsonAchis;
		
		return jsonAchis; 
	}

	public User getUser() {
		return user;
	}

	@Resource
	public void setUser(User user) {
		this.user = user;
	}

	public UserDao getUserDao() {
		return userDao;
	}

	@Resource
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

	public Camp getCamp() {
		return camp;
	}

	@Resource
	public void setCamp(Camp camp) {
		this.camp = camp;
	}

	public CampDao getCampDao() {
		return campDao;
	}

	@Resource
	public void setCampDao(CampDao campDao) {
		this.campDao = campDao;
	}
	public Achi getAchi() {
		return achi;
	}
	
	@Resource
	public void setAchi(Achi achi) {
		this.achi = achi;
	}

	public AppDao getAppDao() {
		return appDao;
	}

	@Resource
	public void setAppDao(AppDao appDao) {
		this.appDao = appDao;
	}
}
